module klang.编译.json.JSON;
import 全局;
import std.conv: ·to = to;
import 核心 = klang.编译.核心.核心_;
import klang.编译.核心.核心_: 整数_;
enum JSON类型_ : byte {
    空值_ = 0,
    文本_ = 1,
    整数_ = 2,
    正整数_ = 3,
    小数_ = 4,
    数组_ = 5,
    对象_ = 6,
    真_ = 7,
    假_ = 8
}
struct JSON值_ {
    private long _序号 = 0;
    private long[dstring] _对象序号 = ··null!(long[dstring]);
    private JSON类型_ _类型 = JSON类型_.空值_;
    private void* _空值 = ··null!(void*);
    dstring 文本_ = ··null!(dstring);
    long 整数_ = ··null!(long);
    ulong 正整数_ = ··null!(ulong);
    double 小数_ = ··null!(double);
    bool 真假_ = ··null!(bool);
    JSON值_[] 数组_ = ··null!(JSON值_[]);
    JSON值_[dstring] 对象_ = ··null!(JSON值_[dstring]);
    this(dstring s) {
        this._类型 = JSON类型_.文本_;
        this.文本_ = s;
    }
    this(JSON值_[] arr) {
        this._类型 = JSON类型_.数组_;
        this.数组_ = arr;
    }
    this(JSON值_[dstring] obj) {
        this._类型 = JSON类型_.对象_;
        this.对象_ = obj;
    }
    this(bool boo) {
        if (boo) {
            this._类型 = JSON类型_.真_;
        }
        else {
            this._类型 = JSON类型_.假_;
        }
        this.真假_ = boo;
    }
    this(int integer) {
        this._类型 = JSON类型_.整数_;
        this.整数_ = integer;
    }
    this(double flo) {
        this._类型 = JSON类型_.小数_;
        this.小数_ = flo;
    }
    JSON类型_ 类型() {
        return this._类型;
    }
    void 设置(dstring k, JSON值_ v) {
        this.对象_[k] = v;
        this._对象序号[k] = this._序号;
        ++this._序号;
    }
    void 设置(dstring k, bool v) {
        this.对象_[k] = .JSON值_(v);
        this._对象序号[k] = this._序号;
        ++this._序号;
    }
    void f·设置(T)(dstring k, T v) {
        if (this._类型 != JSON类型_.对象_) {
            throw new Throwable(·to!(string)(("不是对象"d)));
        }
        else {
            static if (is(T == dstring)) {
                this.对象_[k] = .JSON值_(v);
            }
            static if (is(T == bool)) {
                this.对象_[k] = .JSON值_(v);
            }
            static if (is(T == long)) {
                this.对象_[k] = .JSON值_(v);
            }
            static if (is(T == ulong)) {
                this.对象_[k] = .JSON值_(v);
            }
            static if (is(T == double)) {
                this.对象_[k] = .JSON值_(v);
            }
            static if (is(T == JSON值_[dstring])) {
                this.对象_[k] = .JSON值_(v);
            }
            static if (is(T == JSON值_[])) {
                this.对象_[k] = .JSON值_(v);
            }
            this._对象序号[k] = this._序号;
            ++this._序号;
        }
    }
    void 设置(bool v) {
        this._类型 = v ? JSON类型_.真_ : JSON类型_.假_;
        this.真假_ = v;
    }
    void f·设置(T)(T v) {
        static if (is(T == dstring)) {
            this._类型 = JSON类型_.文本_;
            this.文本_ = v;
        }
        static if (is(T == long)) {
            this._类型 = JSON类型_.整数_;
            this.整数_ = v;
        }
        static if (is(T == ulong)) {
            this._类型 = JSON类型_.正整数_;
            this.正整数_ = v;
        }
        static if (is(T == double)) {
            this._类型 = JSON类型_.小数_;
            this.小数_ = v;
        }
        static if (is(T == JSON值_[dstring])) {
            this._类型 = JSON类型_.对象_;
            this.对象_ = v;
        }
        static if (is(T == JSON值_[])) {
            this._类型 = JSON类型_.数组_;
            this.数组_ = v;
        }
    }
    T f·获取(T)() {
        if (this._类型 == JSON类型_.空值_) {
            throw new Throwable(·to!(string)(("访问空值"d)));
        }
        static if (is(T == dstring)) {
            if (this.类型 != JSON类型_.文本_) {
                throw new Throwable(·to!(string)(("值是文本_"d)));
            }
            return (cast(T)(this.文本_));
        }
        static if (is(T == long)) {
            if (this.类型 != JSON类型_.整数_) {
                throw new Throwable(·to!(string)(("值是整数_"d)));
            }
            return (cast(T)(this.整数_));
        }
        static if (is(T == ulong)) {
            if (this.类型 != JSON类型_.正整数_) {
                throw new Throwable(·to!(string)(("值是正整数_"d)));
            }
            return (cast(T)(this.正整数_));
        }
        static if (is(T == double)) {
            if (this.类型 != JSON类型_.小数_) {
                throw new Throwable(·to!(string)(("值是小数_"d)));
            }
            return (cast(T)(this.小数_));
        }
        static if (is(T == JSON值_[dstring])) {
            if (this.类型 != JSON类型_.对象_) {
                throw new Throwable(·to!(string)(("值是对象_"d)));
            }
            return (cast(T)(this.对象_));
        }
        static if (is(T == JSON值_[])) {
            if (this.类型 != JSON类型_.数组_) {
                throw new Throwable(·to!(string)(("值是数组_"d)));
            }
            return (cast(T)(this.数组_));
        }
        return ··null!(long);
    }
    JSON值_ 获取属性(dstring k) {
        if (this._类型 != JSON类型_.对象_) {
            throw new Throwable(·to!(string)(("不是对象"d)));
        }
        if (.具有!(JSON值_, dstring)(this.对象_, k) !is ··null!(JSON值_*)) {
            return this.对象_[k];
        }
        return .JSON值_();
    }
    dstring 转为文本() {
        if (this._类型 == JSON类型_.空值_) {
            return "null"d;
        }
        if (this._类型 == JSON类型_.文本_) {
            return `"`d ~ this.文本_ ~ `"`d;
        }
        if (this._类型 == JSON类型_.真_) {
            return "ture"d;
        }
        if (this._类型 == JSON类型_.假_) {
            return "false"d;
        }
        if (this._类型 == JSON类型_.整数_) {
            return ·to!(dstring)(this.整数_);
        }
        if (this._类型 == JSON类型_.正整数_) {
            return ·to!(dstring)(this.正整数_);
        }
        if (this._类型 == JSON类型_.小数_) {
            return ·to!(dstring)(this.小数_);
        }
        if (this._类型 == JSON类型_.数组_) {
            dstring[] ret = [];
            foreach (JSON值_ v; this.数组_) {
                .追加!(dstring)(ret, v.转为文本());
            }
            return `[`d ~ 核心.连接(ret, ", "d) ~ `]`d;
        }
        if (this._类型 == JSON类型_.对象_) {
            dstring[] ret = [];
            ret.length = this._序号;
            foreach (dstring k, JSON值_ v; this.对象_) {
                ret[this._对象序号[k]] = `"`d ~ k ~ `": `d ~ v.转为文本() ~ ``d;
            }
            return `{`d ~ 核心.连接(ret, ", "d) ~ `}`d;
        }
        return ""d;
    }
}
JSON值_ 创建JSON空对象() {
    JSON值_ ret = .JSON值_();
    ret._类型 = JSON类型_.对象_;
    return ret;
}
